HAPI Server在return response前會檢查格式,所以如果想對HAPI Server的response進行修改(如因為資安要求,要進行加密),使用JAVA的Intercepter或Filter都做不到,會直接跳errror。
既然這樣只好山不轉路轉,路不轉人轉,人不轉頭轉了。使用Spring Cloud Gateway技術,透過URL mapping到HAPI FHIR Server,讓user使用特定的URL取得處理後的Response。
接下來會介紹如何使用Spring Cloud Gateway來對response進行全域加密。
需要先創建一個新的項目,再在POM檔內import dependency。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.4.23</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
import完dependency後就能進行開發了,主要需要修改兩個檔案,FHIRServerResponseGlobalFilter和application.yml。
FHIRServerResponseGlobalFilter
AESUtils aes = new AESUtils();
@Override
public int getOrder() {
return -1;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
try {
//獲取response的數據
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
HttpStatus statusCode = originalResponse.getStatusCode();
if (statusCode == HttpStatus.OK) {
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
DataBuffer join = dataBufferFactory.join(dataBuffers);
byte[] content = new byte[join.readableByteCount()];
join.read(content);
DataBufferUtils.release(join);
String responseData = new String(content, StandardCharsets.UTF_8);
String AESKey = "1223334444555556";
String encryptedData = aes.encrypt(responseData, AESKey);
System.out.println("AES加密內容 : " + encryptedData);
byte[] uppedContent = new String(encryptedData.getBytes(), Charset.forName("UTF-8")).getBytes();
originalResponse.getHeaders().setContentLength(uppedContent.length);
return bufferFactory.wrap(uppedContent);
}));
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
return chain.filter(exchange);
} catch (Exception e) {
e.printStackTrace();
return chain.filter(exchange);
}
}
}
application.yml
spring.application.name: spring-cloud-gateway
server.port: 8081
## gateway配置
spring:
cloud:
gateway:
routes:
# 註冊的route
- id: test_route
uri: http://127.0.0.1:8080
predicates:
- Path=/encryption/**
filters:
- StripPrefix=1
AES的加密方式非常多,這邊就不貼了,可以依據自己的習慣寫AES加密的方法。
新增完以上程式碼後,記得先執行HAPI Server後再執行Spring Cloud Gateway這個項目。
兩個項目都啟起來後,輸入 http://127.0.0.1:8080/fhir/Observation 後就能取得所有的測量數據。輸入 http://127.0.0.1:8081/encryption/fhir/Observation 後能取得進行AES加密後的所有測量數據。
以上,今天分享一個能對HAPI Server的response進行修改的方法,希望對大家有幫助。